﻿using System;
using System.ComponentModel;

using SBPweb.RIA.Server.Common.Patterns;

using SBPweb.RIA.Shared.Contracts.Components;
using SBPweb.RIA.Shared.Contracts.Events;
using SBPweb.RIA.Shared.Contracts.Logging;

using SBPweb.PROvibe.Server.Core.Modularity;
using SBPweb.PROvibe.Server.Core.Services;

using SBPweb.PROvibe.Server.Library;
using SBPweb.PROvibe.Server.Library.Modularity;
using SBPweb.PROvibe.Server.Library.Services;

namespace SBPweb.PROvibe.Server.Core
{

    public class ServerContext : InitializableBase, IServerContext
    {

        #region Fields

        private static SingletonHelper<ServerContext> sh = new SingletonHelper<ServerContext>(new ServerContextCreator(CreateServerContextInstance));

        #endregion

        #region Constructor logic

        private ServerContext()
        {
            LogManager = SBPweb.PROvibe.Server.Library.Events.LogManager.Logger;
            LogManager.Initialized += new EventHandler(LogManager_Initialized);

            ModuleManager = new ModuleManager();
            ModuleManager.Initializing += new EventHandler<CancelEventArgs>(ModuleManager_Initializing);
            ModuleManager.Initialized += new EventHandler(ModuleManager_Initialized);

            ServiceManager = new ServiceManager();
            ServiceManager.Initializing += new EventHandler<CancelEventArgs>(ServiceManager_Initializing);
            ServiceManager.Initialized += new EventHandler(ServiceManager_Initialized);
        }

        #endregion

        #region Properties

        public static ServerContext Instance
        {
            get
            {
                return sh.Instance;
            }
        }


        public ILogManager LogManager
        {
            get;
            private set;
        }

        public IServiceManager ServiceManager
        {
            get;
            private set;
        }

        public IModuleManager ModuleManager
        {
            get;
            private set;
        }

        #endregion

        #region Delegates

        private delegate ServerContext ServerContextCreator();

        #endregion

        #region Methods

        private static ServerContext CreateServerContextInstance()
        {
            ServerContext context = new ServerContext();
            return context;
        }

        protected override void OnInitialize()
        {
            LogManager.Initialize();
        }

        private void LogManager_Initialized(object sender, EventArgs e)
        {
            LogManager.WriteInfo(this, "The ServerContext has been initialized!", Library.Events.LogManager.Categories.Server.Core);
            ModuleManager.Initialize();
        }
        
        private void ModuleManager_Initializing(object sender, CancelEventArgs e)
        {
            LogManager.WriteInfo(this, "The ModuleManager started initializing...", Library.Events.LogManager.Categories.Server.Core);
        }
        
        private void ModuleManager_Initialized(object sender, EventArgs e)
        {
            LogManager.WriteInfo(this, "The ModuleManager has been initialized!", Library.Events.LogManager.Categories.Server.Core);
            ServiceManager.Initialize();
        }

        private void ServiceManager_Initializing(object sender, CancelEventArgs e)
        {
            LogManager.WriteInfo(this, "The ServiceManager started initializing...", Library.Events.LogManager.Categories.Server.Core);
        }
        
        private void ServiceManager_Initialized(object sender, EventArgs e)
        {
            LogManager.WriteInfo(this, "The Service has been initialized!", Library.Events.LogManager.Categories.Server.Core);
        }

        protected override void OnTerminate()
        {
            LogManager.WriteInfo(this, "The ServerContext has been terminated!", Library.Events.LogManager.Categories.Server.Core);
            LogManager.Terminate();
        }

        #endregion

    }

}